Skip to main content

13 内存管理

独享内存空间的原理

内存都被分成一块一块儿的编好了号这样一个地址,通过这个地址定位到物理内存的位置。

物理地址对于进程不可见,不能直接访问物理地址。操作系统会给进程分配一个虚拟地址。所有进程看到的这个地址都是一样的,里面的内存都是从 0 开始编号。

指令写入的地址是虚拟地址,操作系统会提供一种机制,将不同进程的虚拟地址和不同内存的物理地址映射起来。当程序要访问虚拟地址,由内核的数据结构进行转换,转换成不同的物理地址,不同的进程运行的时候,写入的是不同的物理地址。

规划虚拟地址空间

  • 物理内存的管理
  • 虚拟地址的管理
  • 虚拟地址和物理地址如何映射

程序在使用内存时的几种方式:

  • 代码;
  • 全局变量;
  • 常量字符串;
  • 函数栈;
  • 堆;
  • 对 glibc 的调用,glibc 的代码是以 so 文件的形式存在的,也需要放在内存里面。

内核部分需要分配的内存:

  • 内核的代码;
  • 内核中全局变量;
  • 每个进程的 task_struct;
  • 每个进程的内核栈;
  • 动态分配的内存;
  • 虚拟地址到物理地址的映射表。

虚拟内存中,放内核的部分称为内核空间,放进程的部分称为用户空间。

内存空间从最低位开始:

  • Text Segment 存放二进制可执行代码;
  • Data Segment 存放静态常量;
  • BSS Segment 存放未初始化的静态变量;
  • 堆(Heap)段,用来动态分配内存区域;
  • Memory Mapping Segment,用来把文件映射进内存(动态链接库);
  • 栈(Stack)地址段,存放主线程的函数调用的函数栈;

内存映射

分段

段表,段描述符表(segment descriptors)在全局描述符表 GDT(Global Descriptor Table)里,通过 GDT_ENTRY_INIT 初始化段描述符表里面的表项。

分页(Paging)

把内存分成一块一块大小相同的页,内存页面长时间不用,可以暂时写到硬盘上,称为换出。一旦需要再加载进来,叫做换入。可以扩大可用物理内存的大小,提高物理内存的利用率。

四级目录